home *** CD-ROM | disk | FTP | other *** search
/ CD Actual Thematic 7: Programming / CDAT7.iso / demos / VisualAge for Java 2.0 Entry / setup / data1.cab / ide-e / IDE / cache / 1U11VOR (.txt) < prev    next >
Encoding:
Java Class File  |  1998-09-16  |  11.6 KB  |  543 lines

  1. package com.sun.java.swing.tree;
  2.  
  3. import java.io.IOException;
  4. import java.io.ObjectInputStream;
  5. import java.io.ObjectOutputStream;
  6. import java.io.Serializable;
  7. import java.util.Enumeration;
  8. import java.util.NoSuchElementException;
  9. import java.util.Vector;
  10.  
  11. public class DefaultMutableTreeNode implements Cloneable, MutableTreeNode, Serializable {
  12.    public static final Enumeration EMPTY_ENUMERATION = new 1();
  13.    protected MutableTreeNode parent;
  14.    protected Vector children;
  15.    protected transient Object userObject;
  16.    protected boolean allowsChildren;
  17.  
  18.    public DefaultMutableTreeNode() {
  19.       this((Object)null);
  20.    }
  21.  
  22.    public DefaultMutableTreeNode(Object userObject) {
  23.       this(userObject, true);
  24.    }
  25.  
  26.    public DefaultMutableTreeNode(Object userObject, boolean allowsChildren) {
  27.       this.parent = null;
  28.       this.allowsChildren = allowsChildren;
  29.       this.userObject = userObject;
  30.    }
  31.  
  32.    public void add(MutableTreeNode newChild) {
  33.       if (newChild != null && newChild.getParent() == this) {
  34.          this.insert(newChild, this.getChildCount() - 1);
  35.       } else {
  36.          this.insert(newChild, this.getChildCount());
  37.       }
  38.  
  39.    }
  40.  
  41.    public Enumeration breadthFirstEnumeration() {
  42.       return new BreadthFirstEnumeration(this, this);
  43.    }
  44.  
  45.    public Enumeration children() {
  46.       return this.children == null ? EMPTY_ENUMERATION : this.children.elements();
  47.    }
  48.  
  49.    public Object clone() {
  50.       DefaultMutableTreeNode newNode = null;
  51.  
  52.       try {
  53.          newNode = (DefaultMutableTreeNode)super.clone();
  54.          newNode.children = null;
  55.          newNode.parent = null;
  56.          return newNode;
  57.       } catch (CloneNotSupportedException var3) {
  58.          throw new InternalError(((Throwable)var3).toString());
  59.       }
  60.    }
  61.  
  62.    public Enumeration depthFirstEnumeration() {
  63.       return this.postorderEnumeration();
  64.    }
  65.  
  66.    public boolean getAllowsChildren() {
  67.       return this.allowsChildren;
  68.    }
  69.  
  70.    public TreeNode getChildAfter(TreeNode aChild) {
  71.       if (aChild == null) {
  72.          throw new IllegalArgumentException("argument is null");
  73.       } else {
  74.          int index = this.getIndex(aChild);
  75.          if (index == -1) {
  76.             throw new IllegalArgumentException("node is not a child");
  77.          } else {
  78.             return index < this.getChildCount() - 1 ? this.getChildAt(index + 1) : null;
  79.          }
  80.       }
  81.    }
  82.  
  83.    public TreeNode getChildAt(int index) {
  84.       if (this.children == null) {
  85.          throw new ArrayIndexOutOfBoundsException("node has no children");
  86.       } else {
  87.          return (TreeNode)this.children.elementAt(index);
  88.       }
  89.    }
  90.  
  91.    public TreeNode getChildBefore(TreeNode aChild) {
  92.       if (aChild == null) {
  93.          throw new IllegalArgumentException("argument is null");
  94.       } else {
  95.          int index = this.getIndex(aChild);
  96.          if (index == -1) {
  97.             throw new IllegalArgumentException("argument is not a child");
  98.          } else {
  99.             return index > 0 ? this.getChildAt(index - 1) : null;
  100.          }
  101.       }
  102.    }
  103.  
  104.    public int getChildCount() {
  105.       return this.children == null ? 0 : this.children.size();
  106.    }
  107.  
  108.    public int getDepth() {
  109.       Object last = null;
  110.  
  111.       for(Enumeration enum = this.breadthFirstEnumeration(); enum.hasMoreElements(); last = enum.nextElement()) {
  112.       }
  113.  
  114.       if (last == null) {
  115.          throw new InternalError("nodes should be null");
  116.       } else {
  117.          return ((DefaultMutableTreeNode)last).getLevel() - this.getLevel();
  118.       }
  119.    }
  120.  
  121.    public TreeNode getFirstChild() {
  122.       if (this.getChildCount() == 0) {
  123.          throw new NoSuchElementException("node has no children");
  124.       } else {
  125.          return this.getChildAt(0);
  126.       }
  127.    }
  128.  
  129.    public DefaultMutableTreeNode getFirstLeaf() {
  130.       DefaultMutableTreeNode node;
  131.       for(node = this; !node.isLeaf(); node = (DefaultMutableTreeNode)node.getFirstChild()) {
  132.       }
  133.  
  134.       return node;
  135.    }
  136.  
  137.    public int getIndex(TreeNode aChild) {
  138.       if (aChild == null) {
  139.          throw new IllegalArgumentException("argument is null");
  140.       } else {
  141.          return !this.isNodeChild(aChild) ? -1 : this.children.indexOf(aChild);
  142.       }
  143.    }
  144.  
  145.    public TreeNode getLastChild() {
  146.       if (this.getChildCount() == 0) {
  147.          throw new NoSuchElementException("node has no children");
  148.       } else {
  149.          return this.getChildAt(this.getChildCount() - 1);
  150.       }
  151.    }
  152.  
  153.    public DefaultMutableTreeNode getLastLeaf() {
  154.       DefaultMutableTreeNode node;
  155.       for(node = this; !node.isLeaf(); node = (DefaultMutableTreeNode)node.getLastChild()) {
  156.       }
  157.  
  158.       return node;
  159.    }
  160.  
  161.    public int getLeafCount() {
  162.       int count = 0;
  163.       Enumeration enum = this.breadthFirstEnumeration();
  164.  
  165.       while(enum.hasMoreElements()) {
  166.          TreeNode node = (TreeNode)enum.nextElement();
  167.          if (node.isLeaf()) {
  168.             ++count;
  169.          }
  170.       }
  171.  
  172.       if (count < 1) {
  173.          throw new InternalError("tree has zero leaves");
  174.       } else {
  175.          return count;
  176.       }
  177.    }
  178.  
  179.    public int getLevel() {
  180.       int levels = 0;
  181.  
  182.       for(TreeNode ancestor = this; (ancestor = ((TreeNode)ancestor).getParent()) != null; ++levels) {
  183.       }
  184.  
  185.       return levels;
  186.    }
  187.  
  188.    public DefaultMutableTreeNode getNextLeaf() {
  189.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  190.       if (myParent == null) {
  191.          return null;
  192.       } else {
  193.          DefaultMutableTreeNode nextSibling = this.getNextSibling();
  194.          return nextSibling != null ? nextSibling.getFirstLeaf() : myParent.getNextLeaf();
  195.       }
  196.    }
  197.  
  198.    public DefaultMutableTreeNode getNextNode() {
  199.       if (this.getChildCount() != 0) {
  200.          return (DefaultMutableTreeNode)this.getChildAt(0);
  201.       } else {
  202.          DefaultMutableTreeNode nextSibling = this.getNextSibling();
  203.          if (nextSibling != null) {
  204.             return nextSibling;
  205.          } else {
  206.             for(DefaultMutableTreeNode aNode = (DefaultMutableTreeNode)this.getParent(); aNode != null; aNode = (DefaultMutableTreeNode)aNode.getParent()) {
  207.                nextSibling = aNode.getNextSibling();
  208.                if (nextSibling != null) {
  209.                   return nextSibling;
  210.                }
  211.             }
  212.  
  213.             return null;
  214.          }
  215.       }
  216.    }
  217.  
  218.    public DefaultMutableTreeNode getNextSibling() {
  219.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  220.       DefaultMutableTreeNode retval;
  221.       if (myParent == null) {
  222.          retval = null;
  223.       } else {
  224.          retval = (DefaultMutableTreeNode)myParent.getChildAfter(this);
  225.       }
  226.  
  227.       if (retval != null && !this.isNodeSibling(retval)) {
  228.          throw new InternalError("child of parent is not a sibling");
  229.       } else {
  230.          return retval;
  231.       }
  232.    }
  233.  
  234.    public TreeNode getParent() {
  235.       return this.parent;
  236.    }
  237.  
  238.    public TreeNode[] getPath() {
  239.       return this.getPathToRoot(this, 0);
  240.    }
  241.  
  242.    protected TreeNode[] getPathToRoot(TreeNode aNode, int depth) {
  243.       TreeNode[] retNodes;
  244.       if (aNode == null) {
  245.          if (depth == 0) {
  246.             return null;
  247.          }
  248.  
  249.          retNodes = new TreeNode[depth];
  250.       } else {
  251.          ++depth;
  252.          retNodes = this.getPathToRoot(aNode.getParent(), depth);
  253.          retNodes[retNodes.length - depth] = aNode;
  254.       }
  255.  
  256.       return retNodes;
  257.    }
  258.  
  259.    public DefaultMutableTreeNode getPreviousLeaf() {
  260.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  261.       if (myParent == null) {
  262.          return null;
  263.       } else {
  264.          DefaultMutableTreeNode previousSibling = this.getPreviousSibling();
  265.          return previousSibling != null ? previousSibling.getLastLeaf() : myParent.getPreviousLeaf();
  266.       }
  267.    }
  268.  
  269.    public DefaultMutableTreeNode getPreviousNode() {
  270.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  271.       if (myParent == null) {
  272.          return null;
  273.       } else {
  274.          DefaultMutableTreeNode previousSibling = this.getPreviousSibling();
  275.          if (previousSibling != null) {
  276.             return previousSibling.getChildCount() == 0 ? previousSibling : previousSibling.getLastLeaf();
  277.          } else {
  278.             return myParent;
  279.          }
  280.       }
  281.    }
  282.  
  283.    public DefaultMutableTreeNode getPreviousSibling() {
  284.       DefaultMutableTreeNode myParent = (DefaultMutableTreeNode)this.getParent();
  285.       DefaultMutableTreeNode retval;
  286.       if (myParent == null) {
  287.          retval = null;
  288.       } else {
  289.          retval = (DefaultMutableTreeNode)myParent.getChildBefore(this);
  290.       }
  291.  
  292.       if (retval != null && !this.isNodeSibling(retval)) {
  293.          throw new InternalError("child of parent is not a sibling");
  294.       } else {
  295.          return retval;
  296.       }
  297.    }
  298.  
  299.    public TreeNode getRoot() {
  300.       TreeNode ancestor = this;
  301.  
  302.       Object previous;
  303.       do {
  304.          previous = ancestor;
  305.          ancestor = ancestor.getParent();
  306.       } while(ancestor != null);
  307.  
  308.       return (TreeNode)previous;
  309.    }
  310.  
  311.    public TreeNode getSharedAncestor(DefaultMutableTreeNode aNode) {
  312.       if (aNode == this) {
  313.          return this;
  314.       } else if (aNode == null) {
  315.          return null;
  316.       } else {
  317.          int level1 = this.getLevel();
  318.          int level2 = aNode.getLevel();
  319.          int diff;
  320.          Object node1;
  321.          Object node2;
  322.          if (level2 > level1) {
  323.             diff = level2 - level1;
  324.             node1 = aNode;
  325.             node2 = this;
  326.          } else {
  327.             diff = level1 - level2;
  328.             node1 = this;
  329.             node2 = aNode;
  330.          }
  331.  
  332.          while(diff > 0) {
  333.             node1 = ((TreeNode)node1).getParent();
  334.             --diff;
  335.          }
  336.  
  337.          while(node1 != node2) {
  338.             node1 = ((TreeNode)node1).getParent();
  339.             node2 = ((TreeNode)node2).getParent();
  340.             if (node1 == null) {
  341.                if (node1 == null && node2 == null) {
  342.                   return null;
  343.                }
  344.  
  345.                throw new InternalError("nodes should be null");
  346.             }
  347.          }
  348.  
  349.          return (TreeNode)node1;
  350.       }
  351.    }
  352.  
  353.    public int getSiblingCount() {
  354.       TreeNode myParent = this.getParent();
  355.       return myParent == null ? 1 : myParent.getChildCount();
  356.    }
  357.  
  358.    public Object getUserObject() {
  359.       return this.userObject;
  360.    }
  361.  
  362.    public Object[] getUserObjectPath() {
  363.       TreeNode[] realPath = this.getPath();
  364.       Object[] retPath = new Object[realPath.length];
  365.  
  366.       for(int counter = 0; counter < realPath.length; ++counter) {
  367.          retPath[counter] = ((DefaultMutableTreeNode)realPath[counter]).getUserObject();
  368.       }
  369.  
  370.       return retPath;
  371.    }
  372.  
  373.    public void insert(MutableTreeNode newChild, int childIndex) {
  374.       if (!this.allowsChildren) {
  375.          throw new IllegalStateException("node does not allow children");
  376.       } else if (newChild == null) {
  377.          throw new IllegalArgumentException("new child is null");
  378.       } else if (this.isNodeAncestor(newChild)) {
  379.          throw new IllegalArgumentException("new child is an ancestor");
  380.       } else {
  381.          MutableTreeNode oldParent = (MutableTreeNode)newChild.getParent();
  382.          if (oldParent != null) {
  383.             oldParent.remove(newChild);
  384.          }
  385.  
  386.          newChild.setParent(this);
  387.          if (this.children == null) {
  388.             this.children = new Vector();
  389.          }
  390.  
  391.          this.children.insertElementAt(newChild, childIndex);
  392.       }
  393.    }
  394.  
  395.    public boolean isLeaf() {
  396.       return this.getChildCount() == 0;
  397.    }
  398.  
  399.    public boolean isNodeAncestor(TreeNode anotherNode) {
  400.       if (anotherNode == null) {
  401.          return false;
  402.       } else {
  403.          TreeNode ancestor = this;
  404.  
  405.          while(ancestor != anotherNode) {
  406.             if ((ancestor = ancestor.getParent()) == null) {
  407.                return false;
  408.             }
  409.          }
  410.  
  411.          return true;
  412.       }
  413.    }
  414.  
  415.    public boolean isNodeChild(TreeNode aNode) {
  416.       boolean retval;
  417.       if (aNode == null) {
  418.          retval = false;
  419.       } else if (this.getChildCount() == 0) {
  420.          retval = false;
  421.       } else {
  422.          retval = aNode.getParent() == this;
  423.       }
  424.  
  425.       return retval;
  426.    }
  427.  
  428.    public boolean isNodeDescendant(DefaultMutableTreeNode anotherNode) {
  429.       return anotherNode == null ? false : anotherNode.isNodeAncestor(this);
  430.    }
  431.  
  432.    public boolean isNodeRelated(DefaultMutableTreeNode aNode) {
  433.       return aNode != null && this.getRoot() == aNode.getRoot();
  434.    }
  435.  
  436.    public boolean isNodeSibling(TreeNode anotherNode) {
  437.       boolean retval;
  438.       if (anotherNode == null) {
  439.          retval = false;
  440.       } else if (anotherNode == this) {
  441.          retval = true;
  442.       } else {
  443.          TreeNode myParent = this.getParent();
  444.          retval = myParent != null && myParent == anotherNode.getParent();
  445.          if (retval && !((DefaultMutableTreeNode)this.getParent()).isNodeChild(anotherNode)) {
  446.             throw new InternalError("sibling has different parent");
  447.          }
  448.       }
  449.  
  450.       return retval;
  451.    }
  452.  
  453.    public boolean isRoot() {
  454.       return this.getParent() == null;
  455.    }
  456.  
  457.    public Enumeration pathFromAncestorEnumeration(TreeNode ancestor) {
  458.       return new PathBetweenNodesEnumeration(this, ancestor, this);
  459.    }
  460.  
  461.    public Enumeration postorderEnumeration() {
  462.       return new PostorderEnumeration(this, this);
  463.    }
  464.  
  465.    public Enumeration preorderEnumeration() {
  466.       return new PreorderEnumeration(this, this);
  467.    }
  468.  
  469.    private void readObject(ObjectInputStream s) throws IOException, ClassNotFoundException {
  470.       s.defaultReadObject();
  471.       Object[] tValues = s.readObject();
  472.       if (tValues.length > 0 && tValues[0].equals("userObject")) {
  473.          this.userObject = tValues[1];
  474.       }
  475.  
  476.    }
  477.  
  478.    public void remove(int childIndex) {
  479.       MutableTreeNode child = (MutableTreeNode)this.getChildAt(childIndex);
  480.       this.children.removeElementAt(childIndex);
  481.       child.setParent((MutableTreeNode)null);
  482.    }
  483.  
  484.    public void remove(MutableTreeNode aChild) {
  485.       if (aChild == null) {
  486.          throw new IllegalArgumentException("argument is null");
  487.       } else if (!this.isNodeChild(aChild)) {
  488.          throw new IllegalArgumentException("argument is not a child");
  489.       } else {
  490.          this.remove(this.getIndex(aChild));
  491.       }
  492.    }
  493.  
  494.    public void removeAllChildren() {
  495.       for(int i = this.getChildCount() - 1; i >= 0; --i) {
  496.          this.remove(i);
  497.       }
  498.  
  499.    }
  500.  
  501.    public void removeFromParent() {
  502.       MutableTreeNode parent = (MutableTreeNode)this.getParent();
  503.       if (parent != null) {
  504.          parent.remove(this);
  505.       }
  506.  
  507.    }
  508.  
  509.    public void setAllowsChildren(boolean allows) {
  510.       if (allows != this.allowsChildren) {
  511.          this.allowsChildren = allows;
  512.          if (!this.allowsChildren) {
  513.             this.removeAllChildren();
  514.          }
  515.       }
  516.  
  517.    }
  518.  
  519.    public void setParent(MutableTreeNode newParent) {
  520.       this.parent = newParent;
  521.    }
  522.  
  523.    public void setUserObject(Object userObject) {
  524.       this.userObject = userObject;
  525.    }
  526.  
  527.    public String toString() {
  528.       return this.userObject == null ? null : this.userObject.toString();
  529.    }
  530.  
  531.    private void writeObject(ObjectOutputStream s) throws IOException {
  532.       s.defaultWriteObject();
  533.       Object[] tValues;
  534.       if (this.userObject != null && this.userObject instanceof Serializable) {
  535.          tValues = new Object[]{"userObject", this.userObject};
  536.       } else {
  537.          tValues = new Object[0];
  538.       }
  539.  
  540.       s.writeObject(tValues);
  541.    }
  542. }
  543.